﻿using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using static CommandListPanel.CommandListPanel;

namespace CommandListPanel
{
    /// <summary>
    /// CommandModel.xaml 的交互逻辑
    /// </summary>
    public partial class CommandModel : UserControl
    {
        public CommandModel()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 设置主题颜色
        /// </summary>
        /// <param name="c1"></param>
        /// <param name="c2"></param>
        /// <param name="c3"></param>
        public void SetColors(string c1,string c2,string c3) { 
        
            BlockOutline.Fill = new SolidColorBrush((Color)ColorConverter.ConvertFromString(c1));
            BlockIndexBlank.Fill = new SolidColorBrush((Color)ColorConverter.ConvertFromString(c2));
            BlankDockPanel.Background = new SolidColorBrush((Color)ColorConverter.ConvertFromString(c3));
        }
        /// <summary>
        /// 是否被选中
        /// </summary>
        public bool IsSelected
        {
            get { return (bool)GetValue(IsSelectedProperty); }
            set { SetValue(IsSelectedProperty, value); Console.WriteLine("IsSelectedProperty变化了"); }
        }
        // Using a DependencyProperty as the backing store for IsSelected.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty IsSelectedProperty =
            DependencyProperty.Register("IsSelected", typeof(bool), typeof(CommandModel), new PropertyMetadata(false,new PropertyChangedCallback(OnIsSelectedChanged)));

        private static void OnIsSelectedChanged(object d, DependencyPropertyChangedEventArgs e)
        {
            CommandModel model = (CommandModel)d;
            model.BlockOutline.Stroke = model.IsSelected ? Brushes.LightYellow : Brushes.AliceBlue;

        }





        public int AbsMouseX
        {
            get { return (int)GetValue(AbsMouseXProperty); }
            set { SetValue(AbsMouseXProperty, value); }
        }

        // Using a DependencyProperty as the backing store for AbsMouseX.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty AbsMouseXProperty =
            DependencyProperty.Register("AbsMouseX", typeof(int), typeof(CommandModel), new PropertyMetadata(0));


        public int MyProperty
        {
            get { return (int)GetValue(MyPropertyProperty); }
            set { SetValue(MyPropertyProperty, value); }
        }


        // Using a DependencyProperty as the backing store for MyProperty.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty MyPropertyProperty =
            DependencyProperty.Register("MyProperty", typeof(int), typeof(CommandModel), new PropertyMetadata(0));


        //创建一个自定义属性：idNum整数类型，用于存储索引值
        public int idNum
        {
            get { return (int)GetValue(idNumProperty); }
            set { SetValue(idNumProperty, value); }
        }
        // Using a DependencyProperty as the backing store for idNum.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty idNumProperty =
            DependencyProperty.Register("idNum", typeof(int), typeof(CommandModel), new PropertyMetadata(0,new PropertyChangedCallback(OnidNumChanged)));

        private static void OnidNumChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            Console.WriteLine("idNum变化了");      
        }



        public JObject ScriptCommand
        {
            get { return (JObject)GetValue(ScriptCommandProperty); }
            set { SetValue(ScriptCommandProperty, value); }
        }
        //using a DependencyProperty as the backing store for ScriptCommand.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ScriptCommandProperty =
            DependencyProperty.Register("ScriptCommand", typeof(JObject), typeof(CommandModel), new PropertyMetadata(new JObject(), new PropertyChangedCallback(OnScriptCommandChanged)));

        private static void OnScriptCommandChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            if (sender is CommandModel newCommandModel && e.NewValue is JObject newScriptCommand)
            {
                if (newScriptCommand.ContainsKey("fun_type") && newScriptCommand.ContainsKey("othername"))
                {
                    newCommandModel.Name = newScriptCommand["fun_type"].ToString();
                    newCommandModel.scommandName.Text = newScriptCommand["othername"].ToString();
                    newCommandModel.OpenScriptEdit.Content = newScriptCommand["fun_type"].ToString();
                    newCommandModel.ScriptCommand = newScriptCommand;
                }
            }

        }








        /// <summary>
        /// 创建一个自定义属性：AbsMouse  激活元素的绝对鼠标的坐标
        /// </summary>
        public Point AbsMouse
        {
            get { return (Point)GetValue(AbsMouseProperty); }
            set { SetValue(AbsMouseProperty, value); }
        }


        // Using a DependencyProperty as the backing store for AbsMouse.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty AbsMouseProperty =
            DependencyProperty.Register("AbsMouse", typeof(Point), typeof(CommandModel), new PropertyMetadata(new Point(), new PropertyChangedCallback(AbsMousseChanged)));
        /// <summary>
        /// 阴影显示
        /// </summary>
        public static bool MaskShow = false;
        public static short MaskWork = 0;
        public bool maskshow = false;
        public bool changEnableHead = true;
        public bool changEnableShadow = true;
        /// <summary>
        /// 移动中..
        /// </summary>
        public bool moving = false;

        /// <summary>
        /// mask的尺寸
        /// </summary>
        public double MhLimit = 120, MhStart = 0, MsLimit = 120, MsStart = 0, MLimit = 60;//原始尺寸
        public double mhLimit = 120, mhStart = 0, msLimit = 120, msStart = 0, wLimit = 60;//实际使用的尺寸

        public void ScaleMask(double scaleRecord)
        {
           mhLimit =scaleRecord*MhLimit;
            mhStart =scaleRecord*MhStart;
            msLimit =scaleRecord*MsLimit;
            msStart =scaleRecord*MsStart;
            wLimit =scaleRecord*MLimit;
        }   
        /// <summary>
        /// 当绑定的鼠标绝对坐标，有变化
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        public static void AbsMousseChanged(object sender, DependencyPropertyChangedEventArgs args)
        {
            CommandModel source = (CommandModel)sender;
            if (!source.IsLoaded||!source.IsVisible)
            {
                return;
            }

            //移动的那个就是自己，那么就不用判断了
            if (source.moving)
            {
                return;
            }
            //如果阴影已打开，并且也不是自己，那也与自己无关
            if (MaskShow && !source.maskshow)
                return;
            Rectangle rectangle = sender as Rectangle;
            Window window = Window.GetWindow(source);

            Point p0 = new Point();
            try
            {
                p0 = source.TransformToAncestor(window).Transform(new Point(0, 0));
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);

            }
            Point p1 = source.AbsMouse;
            double dX = p1.X - p0.X, dY = p1.Y - p0.Y;
            //Console.WriteLine(source.Name + "开始监控变化。。。。。---"+dX+"---"+dY);

            /*
             * 逻辑重写
             * * * 头部
             * * * * * 头部约定范围：触发  宽(-wLimit,wLimit) 高(mhStart,mhLimit)
             * * * * * 其它条件：source.changEnableHead
             * * * 底部
             * * * * * 底部约定范围：触发  宽(-mLimit,wLimit) 高(msStart,msLimit)
             * * * * * 其它条件：source.changEnableShadow
             * 满足条件才执行动作
             * 
             */
            ////////////////////////////////头部触发
            if (
                (dX >= -1 * source.wLimit && dX <= source.wLimit)
                &&
                ((dY >= -1 * source.mhLimit && dY < source.mhStart))
                &&
                source.changEnableHead
                &&
                !MaskShow
                )
            {
                if (source.arrangeHead != null&& !source.maskshow)
                {
                    source.arrangeHead();
                }
                MaskShow = true;
                source.maskshow = true;
                source.cmdShadow.Visibility = Visibility.Hidden;
                source.cmdHead.Visibility = Visibility.Visible;
                return;
            }
            ////////////////////////////////底部触发
            if (
                (dX >= -1 * source.wLimit && dX <= source.wLimit)
                &&
                ((dY <= source.msLimit && dY > source.msStart))
                &&
                source.changEnableShadow
                &&
                !MaskShow
                )
            {
                if (source.arrangeShadow != null&& !source.maskshow)
                {
                    source.arrangeShadow();
                }
                MaskShow = true;
                source.maskshow = true;
                source.cmdHead.Visibility = Visibility.Hidden;
                source.cmdShadow.Visibility = Visibility.Visible;
                return;
            }
            ////////////////////////////////重合触发
            if ((dX >= -1 * source.wLimit && dX <= source.wLimit)
                &&
                dY == 0
                && source.changEnableHead
                && !source.moving
                && !MaskShow)
            {
                if (source.arrangeHead != null && !source.maskshow)
                {
                    source.arrangeHead();
                }
                MaskShow = true;
                source.maskshow = true;
                source.cmdShadow.Visibility = Visibility.Hidden;
                source.cmdHead.Visibility = Visibility.Visible;
                return;
            }
            ////////////////////////////////消失触发:头部
            if (
                (dX < -1 * source.wLimit
                ||
                dX > source.wLimit
                ||
                (dY < -1 * source.mhLimit || dY > source.mhStart)
                )
                && !source.moving
                && source.cmdHead.Visibility==Visibility.Visible
                )
            {
                if (source.arrangeDis != null)
                {
                    source.arrangeDis();
                }
                Console.WriteLine(source.Name+"头部消失触发\n");
                source.cmdHead.Visibility = Visibility.Hidden;
                MaskShow = false;
                source.maskshow = false;
                return;

            }
            ////////////////////////////////消失触发:底部
            if (
                (dX < -1 * source.wLimit
                ||
                dX > source.wLimit
                ||
                (dY > source.msLimit || dY < source.msStart)
                )
                && !source.moving
                && source.cmdShadow.Visibility == Visibility.Visible
                )
            {
                if (source.arrangeDis != null)
                {
                    source.arrangeDis();
                }
                Console.WriteLine(source.Name+"底部消失触发\n");
                source.cmdShadow.Visibility = Visibility.Hidden;
                MaskShow = false;
                source.maskshow = false;
                return;
            }
            return;
        }

        private void OpenScriptEdit_Click(object sender, RoutedEventArgs e)
        {
            KnowledgeWindow knowledgeWindow = new KnowledgeWindow(ScriptCommand);
            knowledgeWindow.Show();
        }


        /// <summary>
        /// 委托一件事情
        /// </summary>
        public delegate void ARRange();
        /// <summary>
        /// 用事件的方式执行委托的事情
        /// </summary>
        public event ARRange arrangeDis;
        public event ARRange arrangeHead;
        public event ARRange arrangeShadow;


    }
}
